/*
   Copyright 2007 Carsten Saager (carsten@saager.org)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package org.saager.traits;

/**
 * Replacements for trait-virtual method calls and trait-super.
 * <br></br><br></br>
 * When a locally defined method is invoke from within a trait, the call is resolved by the 
 * standard Java mechanism, thus the membership in a traited object is not considered. By prefixing the call with
 * <br></br><br></br>
 * <code>virtual().myMethodCall();</code>
 * <br></br><br></br>
 * The call to myMethodCall gets dispatched to the traited object.
 * <br></br><br></br>
 * Similarily the use of {@link #overridden()}: The effect is like calling {@link #virtual()} 
 * but only traits added before this trait are considered.
 * 
 * @author Carsten
 *
 * @param <T> A type representing all interfaces implemented by the traited object.
 */
public interface Traited<T> {
	/**
	 * trait-virtual call.
	 * <br></br><br></br>
	 * To invoke a method trait-virtual, invoke it on the return value(). 
	 * The call behaves then as if it has been made on the traited object.
	 * <br></br><br></br>
	 * Use virtual() within a trait to use implementations that precede the implementation in 
	 * this trait. Omit virtual() so that you have the behavior of a non-virtual method
	 * 
	 * @return The traited object
	 */
	T virtual();
	/**
	 * trait-super call.
	 * <br></br><br></br>
	 * To invoke a method in a traite added before this trait in the traited object.
	 * This prevents that the call gets overriden by later added traits.
	 * 
	 * @return The traited object with the traits add before this trait
	 */
	T overridden();
}